/////////////////////////////////////////////////////////////////////////////
/*/	
*	Creator:		Joshua C. Rouzer & Alexander Kahl
*	Title:			Player Ship cpp
*	Last Edited:	07/14/2013
*	Summary:		Functions defining the behavior of player controlled ships
/*/
/////////////////////////////////////////////////////////////////////////////
#include "PlayerShip.h"
#include "Shooter.h"
#include "Rocketeer.h"
#include "Shielder.h"
#include "Helicopter.h"
#include "Mech.h"
#include "Bullet.h"
#include "LevelManager.h"
#include "EntityManager.h"
#include "CSGD_DirectInput.h"
#include "CSGD_TextureManager.h"
#include "CSGD_Direct3D.h"
#include "CSGD_XAudio2.h"
#include "BitmapFont.h"
#include "Game.h"
#include "Economy.h"
#include "SGD_Math.h"
#include <queue>
#include <cassert>
#include <sstream>
#include "BitmapFont.h"
#include "Game.h"
#include "Economy.h"
#include "SGD_Math.h"
#include "ParticleManager.h"
#include <queue>
#include <cassert>
#include <sstream>
#include "AnimInfo.h"

#define SPEED 150
#define SPAWNRANGE 50
#define SHOOTSPEED 100
#define SPECIAL 20

/////////////////////////////////////////////////////////////////////////////
// Function		: Constructor
// Parameters	: _playerTwo - true only if it will control player 2
// Notes		: Assigns default values to the variables
/////////////////////////////////////////////////////////////////////////////
CPlayerShip::CPlayerShip(bool _playerOne, bool _AI){
	m_eType = PLAYER;
	m_Emit = nullptr;
	SetVelX(0.0f);
	SetVelY(0.0f);
	m_bPlayerOne = _playerOne;
	m_fHealth			= m_fTotalHealth = 100;
	m_fAttackCooldown	= 1;
	m_fSpecialCooldown	= SPECIAL;
	m_fBaseDamage		= 20;
	m_fSpecialDamage	= 75;
	m_unCredits			= 0;
	m_nSelectedUnit		= 1;
	m_nBulletFire		= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/Sounds/BulletExplosion.wav"));
	m_nTractor			= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/Sounds/PlayerTractorBeam.wav"));
	m_nDeath			= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/Sounds/SoundTest.wav"));
	m_nRegen			= CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("resource/Sounds/PlayerRegen.wav"));
	if(m_bPlayerOne)
		SetPosX( 100 );
	else
		SetPosX( 700 );
	if(_AI)
		IsAi = true;
	else
		IsAi = false;
	SetPosY( 400 );
	SetWidth( 64 );
	SetHeight( 64 );
	spawnTimer = 0.0f;

	if( _playerOne )
	{
		SetImage( CSGD_TextureManager::GetInstance()->LoadTexture( _T("resource/Images/CrosshairBlue.png") ) );
		SetTeam(1);
	}
	else
	{
		SetImage( CSGD_TextureManager::GetInstance()->LoadTexture( _T("resource/Images/CrosshairRed.png") ) );
		SetTeam(2);
	}

	// The actual ship
	m_cShip = new CMovingObject;
	m_cShip->SetImage( CSGD_TextureManager::GetInstance()->LoadTexture( _T("resource/Images/Saucer.png") ) );
	m_cShip->SetWidth( 64 );
	m_cShip->SetHeight( 35 );

	m_Units[0] = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/Images/SingleSoldierTemp.png"), D3DCOLOR_ARGB(255,255,255,255));
	m_Units[1] = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/Images/Rocketeer.png"), D3DCOLOR_ARGB(255,255,255,255));
	m_Units[2] = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/Images/Shielder.png"), D3DCOLOR_ARGB(255,255,255,255));
	m_Units[3] = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/Images/SingleMechTemp.png"), D3DCOLOR_ARGB(255,255,255,255));
	m_Units[4] = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/Images/HeliTemp.png"), D3DCOLOR_ARGB(255,255,255,255));
	m_nStarImg = CSGD_TextureManager::GetInstance()->LoadTexture(_T("resource/Images/star.png"), D3DCOLOR_ARGB(255,255,255,255));

	IsMoving = IsAbducting = false;
	IsPickingUp = -1;

	AnimSystem = new CAnimationSystem();
	AnimSystem->LoadAnimation("TractorBeamAnim.xml");
	AnimationInfo = new CAnimInfo();
	if(AnimSystem->FindAnimation("Tractor_Beam") != -1)
		AnimationInfo->SetCurrAnim(AnimSystem->FindAnimation("Tractor_Beam"));
	else
		AnimationInfo->SetCurrAnim(0);
	AnimationInfo->SetOwner(this);

	CurrAnim = AnimSystem->GetAnimations()[AnimationInfo->GetCurrAnim()];
	CurrAnim->SetImageID(AnimSystem->GetAnimations()[AnimationInfo->GetCurrAnim()]->GetImageID());
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Destructor
// Notes		: Cleans up any dynamically allocated memory
/////////////////////////////////////////////////////////////////////////////
CPlayerShip::~CPlayerShip()
{
	if(m_Emit != nullptr){
		m_Emit->Clear();
		CParticleManager::GetInstance()->RemoveEmitter(m_Emit);
	}
	delete AnimationInfo;
	delete AnimSystem;
	delete m_cShip;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: ThrowDeath
// Notes		: Player dies, sound is made
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::ThrowDeath()
{
	if(GetHealth() <= 0 && !CSGD_XAudio2::GetInstance()->SFXIsSoundPlaying(GetDeathSoundID()))
		CSGD_XAudio2::GetInstance()->SFXPlaySound(GetDeathSoundID());
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Operator ==
// Notes		: Tests to see if the player ships are the same ship
/////////////////////////////////////////////////////////////////////////////
bool CPlayerShip::operator==(CPlayerShip &check){
	bool _return = true;
	if(GetHealth() != check.GetHealth() || GetAttackCool() != check.GetAttackCool()
		|| GetSpecialCool() != check.GetSpecialCool() || GetBaseDmg() != check.GetBaseDmg()
		|| GetSpecialDmg() != check.GetSpecialDmg() || GetCredits() != check.GetCredits()){
			_return = false;
	}
	if(GetVelX() != check.GetVelX() || GetVelY() != check.GetVelY()){
		_return = false;
	}
	if(GetPosX() != check.GetPosX() || GetPosY() != check.GetPosY()
		|| GetWidth() != check.GetWidth() || GetHeight() != check.GetHeight()
		|| GetRotation() != check.GetRotation() || GetImage() != check.GetImage()){
			_return = false;
	}
	return _return;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Update
// Parameters	: dT - Time elapsed since last update
// Notes		: Gets user input and updates the ship based on elapsed time
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::Update(float dT){
	//update cooldowns	
	SetAttackCool(GetAttackCool() - dT);

	if( GetSpecialCool() < SPECIAL )
	{
		SetSpecialCool(GetSpecialCool() - dT);
		if( GetSpecialCool() <= 0 )
			SetSpecialCool( SPECIAL );
	}

	CSGD_DirectInput *pDI = CSGD_DirectInput::GetInstance();

	// Get Level
	CLevel* CurLevel = CLevelManager::GetInstance()->GetCurrLevel();

	// Reset Velocities
	if(!IsAi || m_bPlayerOne){
		SetVelX(0);
		SetVelY(0);
	}

#if _DEBUG
	if(pDI->KeyPressed(DIK_F1) == true)
		IsAi = !IsAi;
#endif
	if(m_Emit != nullptr){
		m_Emit->SetPos(GetShip()->GetPosX(), GetShip()->GetPosY());
	}
	//Over base health regeneration
	if(IsAboveOwnBase()){
		if(GetHealth() < GetTotalHealth()){
			SetHealth(GetHealth() + (15 * dT));				
			if(!CSGD_XAudio2::GetInstance()->SFXIsSoundPlaying(m_nRegen)){
				CSGD_XAudio2::GetInstance()->SFXPlaySound(m_nRegen);
			}
			if(m_Emit == nullptr){
				m_Emit = new CEmitter();
				m_Emit->LoadXML("HealthRegenPart.xml");
				m_Emit->SetPos( GetShip()->GetPosX() - (GetShip()->GetWidth() * 2), GetShip()->GetPosY() - (GetShip()->GetHeight() * 2));
				m_Emit->SetPos2(GetShip()->GetPosX() + (GetShip()->GetWidth() * 2), GetShip()->GetPosY() + (GetShip()->GetHeight() * 2));
				CParticleManager::GetInstance()->AddEmitter(m_Emit);
			}
		}
		else{
			CSGD_XAudio2::GetInstance()->SFXStopSound(m_nRegen);
			if(m_Emit != nullptr){
				CParticleManager::GetInstance()->RemoveEmitter(m_Emit);
				m_Emit = nullptr;
			}
		}
	}
	else if(m_Emit != nullptr){
		CParticleManager::GetInstance()->RemoveEmitter(m_Emit);
		m_Emit = nullptr;
	}

	//Check for user input based on which player
	if(IsAi && !m_bPlayerOne)
	{
		if(IsMoving == false)
		{
			int weakest = -1;
			std::vector<CBaseUnit*> AIUnits;
			for (int i = 0; i < 4; i++)
			{
				switch(i - 1)
				{
				case 0:
					AIUnits = CurLevel->GetTeam2()->GetPath1Units();
					break;
				case 1:
					AIUnits = CurLevel->GetTeam2()->GetPath2Units();
					break;
				case 2:
					AIUnits = CurLevel->GetTeam2()->GetPath3Units();
					break;
				default:
					if(CurLevel->GetTeam1()->GetPath1Units().size() < CurLevel->GetTeam2()->GetPath1Units().size() &&
						CurLevel->GetTeam1()->GetPath2Units().size() < CurLevel->GetTeam2()->GetPath2Units().size() &&
						CurLevel->GetTeam1()->GetPath3Units().size() < CurLevel->GetTeam2()->GetPath3Units().size())
					{}
					else
					{
						weakest = 0;
						IsPickingUp = -1;
						if(AICrate != nullptr)
						{
							CurrAnim->Pause(*AnimationInfo);
							AICrate->SetAIPickUp(false);
						}
					}
					break;
				}



				switch(i - 1)
				{
				case 0:
					if(CurLevel->GetTeam1()->GetPath1Units().size() >= AIUnits.size())
						weakest = i - 1;
					break;
				case 1:
					if(CurLevel->GetTeam1()->GetPath2Units().size() >= AIUnits.size())
						weakest = i - 1;
					break;
				case 2:
					if(CurLevel->GetTeam1()->GetPath3Units().size() >= AIUnits.size())
						weakest = i - 1;
					break;
				}
				if( (int)GetCredits() < CEconomy::GetInstance()->GetUnitCost(SHOOT))
				{

					SetVelX(0.0f);
					SetVelY(0.0f);
					GetClosestCrate();
				}
				else if(weakest != -1)
				{
					targetPath = weakest;
					IsMoving = true;
					SetVelX(0.0f);
				}
			}
		}
		else
		{
			CWaypoint* wpt;
			std::vector<CWaypoint*> wpts;


			switch(targetPath)
			{
			case 0:
				wpts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints();
				if(GetPosY() + GetHeight() / 2 > wpts[wpts.size() - 1]->GetPos().m_nPosY - SPAWNRANGE)
					SetVelY(-SPEED);
				else if(GetPosY() + GetHeight() / 2 < wpts[wpts.size() - 1]->GetPos().m_nPosY + SPAWNRANGE)
					SetVelY(SPEED);
				break;
			case 1:
				wpts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints();
				if(GetPosY() + GetHeight() / 2 > wpts[wpts.size() - 1]->GetPos().m_nPosY - SPAWNRANGE)
					SetVelY(-SPEED);
				else if(GetPosY() + GetHeight() / 2 < wpts[wpts.size() - 1]->GetPos().m_nPosY + SPAWNRANGE)
					SetVelY(SPEED);
				break;
			case 2:
				wpts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints();
				if(GetPosY() + GetHeight() / 2 > wpts[wpts.size() - 1]->GetPos().m_nPosY - SPAWNRANGE)
					SetVelY(-SPEED);
				else if(GetPosY() + GetHeight() / 2 < wpts[wpts.size() - 1]->GetPos().m_nPosY + SPAWNRANGE)
					SetVelY(SPEED);
				break;
			}

			switch(targetPath)
			{
			case 0:
				// Loop through Path 1 waypoints

				for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints().size(); ++i )
				{
					// Cursor close to waypoint
					wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[i];

					if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
					{
						IsMoving = false;
						SpawnUnit(targetPath + 1,false,(float)wpt->GetPos().m_nPosY);
						break;
					}
				}
				break;
			case 1:
				// Loop through Path 2 waypoints

				for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints().size(); ++i )
				{
					// Cursor close to waypoint
					wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[i];

					if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
					{
						IsMoving = false;
						SpawnUnit(targetPath + 1,false,(float)wpt->GetPos().m_nPosY);
						break;
					}
				}
				break;
			case 2:
				// Loop through Path 3 waypoints

				for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints().size(); ++i )
				{
					// Cursor close to waypoint
					wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints()[i];

					if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
					{
						IsMoving = false;
						SpawnUnit(targetPath + 1,false,(float)wpt->GetPos().m_nPosY);
						break;
					}
				}
				break;
			}
		}
		/*if(GetVelY() == 0)
		SetVelY(SPEED);
		if(GetPosY() + GetHeight() > CurLevel->GetField().m_nHeight)
		SetVelY(-SPEED);
		if(GetPosY() < CurLevel->GetField().m_nBgHeight)
		SetVelY(SPEED);*/
	}
	else
	{
		if(m_bPlayerOne){

			//Horizontal movement
			if((pDI->KeyDown(DIK_A) || pDI->JoystickGetLStickDirDown(DIR_LEFT) == true) && GetPosX() + GetWidth()/2 > 0 ){//Left
				SetVelX( -SPEED );
			}
			else if((pDI->KeyDown(DIK_D) || pDI->JoystickGetLStickDirDown(DIR_RIGHT)== true) && (GetPosX() + GetWidth()/2 < CurLevel->GetField().m_nWidth) ){//Right
				SetVelX( SPEED );
			}

			//Vertical movement
			if((pDI->KeyDown(DIK_W) || pDI->JoystickGetLStickDirDown(DIR_UP)== true) && (GetPosY() + GetHeight()/2 > CurLevel->GetField().m_nBgHeight) ){//Up
				SetVelY( -SPEED );
			}
			else if((pDI->KeyDown(DIK_S) || pDI->JoystickGetLStickDirDown(DIR_DOWN)== true) && (GetPosY() + GetHeight()/2 < CurLevel->GetField().m_nHeight) ){//Down
				SetVelY( SPEED );
			}

			else
				pDI->JoystickGetLStickDirPressed(DIR_LEFT);

			//Perform special secondary attack
			if(pDI->KeyPressed(DIK_LSHIFT) || pDI->JoystickButtonPressed(7) == true){
				//Check cooldown

				//Perform special attack

				CBullet* bullet = new CBullet( this );
				bullet->SetImage( CSGD_TextureManager::GetInstance()->LoadTexture( _T("resource/Images/Rocket.png") ) );
				bullet->SetPosX( GetShip()->GetPosX() + GetShip()->GetWidth()/2 );
				bullet->SetPosY( GetShip()->GetPosY() + GetShip()->GetHeight()/2 );
				bullet->SetWidth(20);
				bullet->SetHeight(8);
				bullet->SetRotation( 0.5f );
				bullet->SetPath(0);
				bullet->SetDeathY( (int)GetPosY() + GetHeight()/2 );
				bullet->SetType(MISSILE);
				bullet->SetDamage( 100 );

				bullet->SetVelX( 0 );
				bullet->SetVelY( SHOOTSPEED );
				CEntityManager::GetInstance()->AddEntity(bullet);

				CSGD_XAudio2::GetInstance()->SFXPlaySound(m_nBulletFire);

				SetSpecialCool( GetSpecialCool() - 0.1f );
			}
			//Picking up a crate
			if(pDI->KeyDown(DIK_Z)|| pDI->JoystickButtonPressed(4) == true){

				RECT reticle = { (LONG)(GetPosX()), (LONG)(GetPosY()), (LONG)(GetPosX() + GetWidth()), (LONG)(GetPosY() + GetHeight()) };
				RECT intersect;

				for (unsigned int i = 0; i < CEntityManager::GetInstance()->m_Crates.size(); i++)
				{
					vector<CCrate*> CrateVec = CEntityManager::GetInstance()->m_Crates;

					RECT crate = { (LONG)(CrateVec[i]->GetPosX()), (LONG)(CrateVec[i]->GetCurrPos()),(LONG)( CrateVec[i]->GetPosX() + CrateVec[i]->GetWidth()),
						(LONG)(CrateVec[i]->GetCurrPos() + CrateVec[i]->GetHeight()) };



					if(IntersectRect(&intersect, &reticle, &crate) == TRUE && CrateVec[i]->IsAbducted() == false)
					{
						CrateVec[i]->SetAbducted(true);
						if(AnimationInfo->GetIsPlaying() == false)
							CurrAnim->Play(AnimationInfo->GetFlipped(),CurrAnim->GetIsLoop(),*AnimationInfo);
					}

					RECT player = { (LONG)(GetShip()->GetPosX()), (LONG)(GetShip()->GetPosY()), (LONG)(GetShip()->GetPosX() + GetShip()->GetWidth()),
						(LONG)(GetShip()->GetPosY() + GetShip()->GetHeight()) };
					RECT Collide;

					if(IntersectRect(&Collide, &player, &crate) == TRUE)
					{
						SetCredits(GetCredits() + CrateVec[i]->GetCredits());
						CEntityManager::GetInstance()->RemoveEntity(CEntityManager::GetInstance()->m_Crates[i]);
					}
				}
			}
			//Drop the crate
			if(pDI->KeyUp(DIK_Z) && pDI->KeyDown(DIK_PERIOD) != true)
			{

				for (unsigned int i = 0; i < CEntityManager::GetInstance()->m_Crates.size(); i++)
				{
					if(CEntityManager::GetInstance()->m_Crates[i]->IsAbducted() == true && i != IsPickingUp && CEntityManager::GetInstance()->m_Crates[i]->GetAIPickUp() == false)
						CEntityManager::GetInstance()->m_Crates[i]->SetAbducted(false);
				}
				CurrAnim->Pause(*AnimationInfo);
			}
			//Drop down a barricade
			if(pDI->KeyPressed(DIK_B) || pDI->JoystickButtonPressed(6) == true){
				CWaypoint* point = IsAboveBuildpoint();


				if( point != nullptr && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(BARRICADE))
				{
					CEconomy::GetInstance()->BoughtBarricade(this);
					CBarricade* barricade = new CBarricade(m_bPlayerOne);
					barricade->SetTeam(m_bPlayerOne ? 1 : 2);
					barricade->SetPosX( point->GetPos().m_nPosX - barricade->GetWidth()/2 );
					barricade->SetPosY( point->GetPos().m_nPosY - barricade->GetHeight()/2 );

					if( barricade->GetTeam() == 1 )
						CurLevel->GetTeam1()->AddBarricade( point->GetPathID(), barricade );
					else
						CurLevel->GetTeam2()->AddBarricade( point->GetPathID(), barricade );

					CEntityManager::GetInstance()->AddEntity(barricade);
				}
			}
			//Perform upgrading
			if(pDI->KeyPressed(DIK_U)){
				//Find out what (if anything upgradable) it's above
				CBarricade *barr = IsAboveBarricade();
				if(barr != nullptr){
					//Then deal with that barricade's upgrade
					if(barr->GetLevel() < 5){
						barr->Upgrade();
					}
				}
				else if(IsAboveOwnBase()){
					//Then deal with the base upgrade
					if(m_bPlayerOne){
						CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->GetBase()->Upgrade();
					}
					else{
						CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->GetBase()->Upgrade();
					}
				}
			}
			//Change selected unit type
			if(pDI->KeyPressed(DIK_LEFT) && m_nSelectedUnit > 1)
				m_nSelectedUnit--;
			else if(pDI->KeyPressed(DIK_RIGHT) && m_nSelectedUnit < 5)
				m_nSelectedUnit++;
		}

		else{//Player 2
			//Horizontal movement
			if(pDI->KeyDown(DIK_LEFTARROW) && GetPosX() > 0 ){//Left
				SetVelX(-SPEED);
			}
			else if(pDI->KeyDown(DIK_RIGHTARROW) && (GetPosX() + GetWidth() < CurLevel->GetField().m_nWidth) ){//Right
				SetVelX(SPEED);
			}
			//Vertical movement
			if(pDI->KeyDown(DIK_UPARROW) && (GetPosY() > CurLevel->GetField().m_nBgHeight) ){//Up
				SetVelY(-SPEED);
			}
			else if(pDI->KeyDown(DIK_DOWNARROW) && (GetPosY() + GetHeight() < CurLevel->GetField().m_nHeight) ){//Down
				SetVelY(SPEED);
			}
			if(pDI->KeyPressed(DIK_RSHIFT)){//Fire special attack
				//Check cooldown
				if(GetSpecialCool() <= 0.0f){
					//Perform special attack
				}
			}
			if(pDI->KeyPressed(DIK_PERIOD)){//Pick up crate

				RECT reticle = { (LONG)(GetPosX()), (LONG)(GetPosY()), (LONG)(GetPosX()) + (LONG)(GetWidth()), (LONG)(GetPosY()) + (LONG)(GetHeight()) };
				RECT intersect;

				for (unsigned int i = 0; i < CEntityManager::GetInstance()->m_Crates.size(); i++)
				{
					vector<CCrate*> CrateVec = CEntityManager::GetInstance()->m_Crates;

					RECT crate = { (LONG)(CrateVec[i]->GetPosX()), (LONG)(CrateVec[i]->GetCurrPos()), (LONG)(CrateVec[i]->GetPosX() + CrateVec[i]->GetWidth()),
						(LONG)(CrateVec[i]->GetCurrPos() + CrateVec[i]->GetHeight()) };



					if(IntersectRect(&intersect, &reticle, &crate) == TRUE && CrateVec[i]->IsAbducted() == false)
					{
						CrateVec[i]->SetAbducted(true);
						if(AnimationInfo->GetIsPlaying() == false)
							CurrAnim->Play(AnimationInfo->GetFlipped(),CurrAnim->GetIsLoop(),*AnimationInfo);
					}

					RECT player = { (LONG)(GetShip()->GetPosX()), (LONG)(GetShip()->GetPosY()), (LONG)(GetShip()->GetPosX() + GetShip()->GetWidth()),
						(LONG)(GetShip()->GetPosY() + GetShip()->GetHeight()) };
					RECT Collide;

					if(IntersectRect(&Collide, &player, &crate) == TRUE)
					{
						SetCredits(GetCredits() + CrateVec[i]->GetCredits());
						CEntityManager::GetInstance()->RemoveEntity(CEntityManager::GetInstance()->m_Crates[i]);
					}
				}

			}

			if(pDI->KeyUp(DIK_PERIOD) && pDI->KeyDown(DIK_Z) != true)
			{

				for (unsigned int i = 0; i < CEntityManager::GetInstance()->m_Crates.size(); i++)
				{
					if(CEntityManager::GetInstance()->m_Crates[i]->IsAbducted() == true && i != IsPickingUp  && CEntityManager::GetInstance()->m_Crates[i]->GetAIPickUp() == false)
						CEntityManager::GetInstance()->m_Crates[i]->SetAbducted(false);
				}
				CurrAnim->Pause(*AnimationInfo);
			}

			if(pDI->KeyPressed(DIK_SLASH)){//Drop barracade

			}

			if(pDI->KeyPressed(DIK_NUMPAD4) && m_nSelectedUnit > 1)
				m_nSelectedUnit--;
			else if(pDI->KeyPressed(DIK_NUMPAD6) && m_nSelectedUnit < 5)
				m_nSelectedUnit++;
		}
	}

	CMovingObject::Update(dT);

	m_cShip->SetPosX( GetPosX() );
	m_cShip->SetPosY( (GetPosY() - 200) / 2 );

	GodSpawnUnits(pDI);

	//Auto-turret attack
	//Check cooldown
	if(GetAttackCool() <= 0.0f){
		CMovingObject* pTarget;

		//Check if an enemy ship is in range

		if( m_bPlayerOne && CLevelManager::GetInstance()->GetCurrLevel()->m_bBossLevel == false )
			pTarget = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->GetPlayerShip()->GetShip();
		else
			pTarget = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->GetPlayerShip()->GetShip();
		if( IsCloseToShip( pTarget ) )
		{
			// Fire!
			CBullet* bullet = new CBullet( this );
			bullet->SetImage( CSGD_TextureManager::GetInstance()->LoadTexture( _T("resource/Images/Bullet.png") ) );
			bullet->SetPosX( GetShip()->GetPosX() + GetShip()->GetWidth()/2 );
			bullet->SetPosY( GetShip()->GetPosY() + GetShip()->GetHeight()/2 );
			bullet->SetWidth(8);
			bullet->SetHeight(8);
			bullet->SetPath(0);
			bullet->SetDeathY( CLevelManager::GetInstance()->GetCurrLevel()->GetField().m_nBgHeight );

			tVector2D vTarget = { (pTarget->GetPosX()+pTarget->GetWidth()/2) - bullet->GetPosX(), 
				(pTarget->GetPosY()+pTarget->GetHeight()/2) - bullet->GetPosY()};
			vTarget = Vector2DNormalize(vTarget);

			bullet->SetVelX( vTarget.fX * SHOOTSPEED );
			bullet->SetVelY( vTarget.fY * SHOOTSPEED );
			CEntityManager::GetInstance()->AddEntity(bullet);

			CSGD_XAudio2::GetInstance()->SFXPlaySound(m_nBulletFire);
		}
		// Check if cursor is above a unit
		else
		{
			pTarget = IsAboveUnit();
			if( pTarget )
			{
				CBullet* bullet = new CBullet( this );
				bullet->SetImage( CSGD_TextureManager::GetInstance()->LoadTexture( _T("resource/Images/Bullet.png") ) );
				bullet->SetPosX( GetShip()->GetPosX() + GetShip()->GetWidth()/2 );
				bullet->SetPosY( GetShip()->GetPosY() + GetShip()->GetHeight()/2 );
				bullet->SetWidth(8);
				bullet->SetHeight(8);
				bullet->SetPath(pTarget->GetPath());
				//assert( bullet->GetPath() > 0 && bullet->GetPath() < 3 && "Bullet has invalid path - CPlayerShip::Update" );
				bullet->SetDeathY((int)pTarget->GetPosY()+pTarget->GetHeight());

				tVector2D vTarget = { (pTarget->GetPosX()+pTarget->GetWidth()/2) - bullet->GetPosX(), 
					(pTarget->GetPosY()+pTarget->GetHeight()/2) - bullet->GetPosY()};
				vTarget = Vector2DNormalize(vTarget);

				bullet->SetVelX( vTarget.fX * SHOOTSPEED );
				bullet->SetVelY( vTarget.fY * SHOOTSPEED );
				CEntityManager::GetInstance()->AddEntity(bullet);
			}
		}
		SetAttackCool( 0.5f );
	}
	AnimSystem->Update(dT,AnimationInfo);
	spawnTimer += dT;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Get Closest Crate
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::GetClosestCrate()
{
	std::vector<CCrate*> crates;
	crates = CEntityManager::GetInstance()->m_Crates;

	CCrate* closest;
	CCrate* EMPTY = new CCrate();
	closest = EMPTY;

	for(unsigned int i = 0; i < crates.size(); i++)
	{
#if _DEBUG
		int k = DistanceBetween(crates[i]->GetPos(),GetPos());
		int j = DistanceBetween(closest->GetPos(),GetPos());
#endif

		if(DistanceBetween(crates[i]->GetPos(),GetPos()) < DistanceBetween(closest->GetPos(),GetPos()) )
			if(crates[i]->GetCurrPos() > 64)
				AICrate = closest = crates[i];
	}

	if( AICrate != EMPTY && AICrate != nullptr )
	{
		RECT reticle = { (LONG)(GetPosX()), (LONG)(GetPosY()), (LONG)(GetPosX() + GetWidth()), (LONG)(GetPosY() + GetHeight()) };
		RECT intersect;

		RECT crate = { (LONG)(AICrate->GetPosX()), (LONG)(AICrate->GetCurrPos()),(LONG)( AICrate->GetPosX() + AICrate->GetWidth()),
			(LONG)(AICrate->GetCurrPos() + AICrate->GetHeight()) };

		if(IntersectRect(&intersect, &reticle, &crate) == FALSE && AICrate->IsAbducted() == false)
		{
			if(GetPos().m_nPosX + (GetWidth() / 2) > AICrate->GetPos().m_nPosX + (AICrate->GetWidth() / 2))
				SetVelX(-SPEED);
			if(GetPos().m_nPosX + (GetWidth() / 2) < AICrate->GetPos().m_nPosX + (AICrate->GetWidth() / 2))
				SetVelX(SPEED);

			if(GetPos().m_nPosY + (GetHeight() / 2) > AICrate->GetCurrPos() + (AICrate->GetHeight() / 2))
				SetVelY(-SPEED);													
			if(GetPos().m_nPosY + (GetHeight() / 2) < AICrate->GetCurrPos() + (AICrate->GetHeight() / 2))
				SetVelY(SPEED);
		}
		else
		{
			SetVelX(0.0f);
			SetVelY(0.0f);
			PickUpCrate(AICrate);
		}
	}

	delete EMPTY;
	EMPTY = nullptr;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Pick up crate
// Parameters	: i - The crate to be picked up
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::PickUpCrate(CCrate* i)
{
	RECT reticle = { (LONG)(GetPosX()), (LONG)(GetPosY()), (LONG)(GetPosX() + GetWidth()), (LONG)(GetPosY() + GetHeight()) };
	RECT intersect;

	RECT crate = { (LONG)(i->GetPosX()), (LONG)(i->GetCurrPos()),(LONG)( i->GetPosX() + i->GetWidth()),
		(LONG)(i->GetCurrPos() + i->GetHeight()) };



	if(IntersectRect(&intersect, &reticle, &crate) == TRUE && i->IsAbducted() == false)
	{
		SetVelX(0.0f);
		SetVelY(0.0f);
		i->SetAIPickUp(true);
		i->SetAbducted(true);
		if(AnimationInfo->GetIsPlaying() == false)
			CurrAnim->Play(AnimationInfo->GetFlipped(),CurrAnim->GetIsLoop(),*AnimationInfo);
	}

	RECT player = { (LONG)(GetShip()->GetPosX()), (LONG)(GetShip()->GetPosY()), (LONG)(GetShip()->GetPosX() + GetShip()->GetWidth()),
		(LONG)(GetShip()->GetPosY() + GetShip()->GetHeight()) };

	if(IntersectRect(&intersect, &player, &crate) == TRUE)
	{
		SetCredits(GetCredits() + i->GetCredits());
		CEntityManager::GetInstance()->RemoveEntity(i);

		AICrate = nullptr;
		CurrAnim->Pause(*AnimationInfo);
	}
}
/////////////////////////////////////////////////////////////////////////////
// Function		: SpawnUnits
// Notes		: helper function for spawning units
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::SpawnUnit(int Path, bool TeamOne, float PosY){
	CEntityManager* EM = CEntityManager::GetInstance();

	// Default unit values
	CBaseUnit* unit = nullptr;

	switch (Path)
	{
	case 1:
		{

			if(m_nSelectedUnit == 1 && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(SHOOT))
			{
				unit = new CShooter;

				CEconomy::GetInstance()->BoughtShooter(this);
			}
			else if(m_nSelectedUnit == 2 && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(ROCKET))
			{
				unit = new CRocketeer;

				CEconomy::GetInstance()->BoughtRocketeer(this);
			}
			else if(m_nSelectedUnit == 3 && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(SHIELD))
			{
				unit = new CShielder;

				CEconomy::GetInstance()->BoughtShielder(this);
			}
			else if(m_nSelectedUnit == 4 && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(MECH))
			{
				unit = new CMech;

				CEconomy::GetInstance()->BoughtMech(this);
			}
			else if(m_nSelectedUnit == 5 && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(HELI))
			{
				unit = new CHelicopter;
				CEconomy::GetInstance()->BoughtHeli(this);
			}

			if(unit == nullptr)
				return;

			int size = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints().size();
			assert( size > 0 && "Path 1 does not have waypoints - PlayerShip::Update" );

			if(TeamOne)
			{
				unit->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[0] );
				unit->SetTeam(1);
				unit->SetPosX(0);
				CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->AddUnit( 1, unit );
			}
			else
			{
				unit->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[size-1] );
				unit->SetTeam(2);
				unit->SetPosX(750);
				CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->AddUnit( 1, unit );
			}
		}
		break;
	case 2:
		{

			if(m_nSelectedUnit == 1 && (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(SHOOT))
			{
				unit = new CShooter;

				CEconomy::GetInstance()->BoughtShooter(this);
			}
			else if(m_nSelectedUnit == 2&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(ROCKET))
			{
				unit = new CRocketeer;

				CEconomy::GetInstance()->BoughtRocketeer(this);
			}
			else if(m_nSelectedUnit == 3&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(SHIELD))
			{
				unit = new CShielder;

				CEconomy::GetInstance()->BoughtShielder(this);
			}
			else if(m_nSelectedUnit == 4&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(MECH))
			{
				unit = new CMech;

				CEconomy::GetInstance()->BoughtMech(this);
			}
			else if(m_nSelectedUnit == 5&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(HELI))
			{
				unit = new CHelicopter;
				CEconomy::GetInstance()->BoughtHeli(this);
			}

			if(unit == nullptr)
				return;

			int size = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints().size();
			assert( size > 0 && "Path 2 does not have waypoints - PlayerShip::Update" );
			if(TeamOne)
			{
				unit->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[0] );
				unit->SetTeam(1);
				unit->SetPosX( 0 );
				CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->AddUnit( 2, unit );
			}
			else
			{
				unit->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[size-1] );
				unit->SetTeam(2);
				unit->SetPosX( 750 );
				CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->AddUnit( 2, unit );
			}
		}
		break;
	case 3:
		{

			if(m_nSelectedUnit == 1&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(SHOOT))
			{
				unit = new CShooter;

				CEconomy::GetInstance()->BoughtShooter(this);
			}
			else if(m_nSelectedUnit == 2&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(ROCKET))
			{
				unit = new CRocketeer;

				CEconomy::GetInstance()->BoughtRocketeer(this);
			}
			else if(m_nSelectedUnit == 3&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(SHIELD))
			{
				unit = new CShielder;

				CEconomy::GetInstance()->BoughtShielder(this);
			}
			else if(m_nSelectedUnit == 4&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(MECH))
			{
				unit = new CMech;

				CEconomy::GetInstance()->BoughtMech(this);
			}
			else if(m_nSelectedUnit == 5&& (int)GetCredits() >= CEconomy::GetInstance()->GetUnitCost(HELI))
			{
				unit = new CHelicopter;
				CEconomy::GetInstance()->BoughtHeli(this);
			}

			if(unit == nullptr)
				return;

			int size = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints().size();
			assert( size > 0 && "Path 3 does not have waypoints - PlayerShip::Update" );
			if(TeamOne)
			{
				unit->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints()[0] );
				unit->SetTeam(1);
				unit->SetPosX( 0 );
				CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->AddUnit( 3, unit );
			}
			else
			{
				unit->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints()[size-1] );
				unit->SetTeam(2);
				unit->SetPosX( 750 );
				CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->AddUnit( 3, unit );
			}
		}
		break;
	default:
		unit = new CBaseUnit;
		assert( Path > 3 && Path < 1 && "Passing in incorrect path - PlayerShip::SpawnUnit" );
		break;
	}


	unit->SetPosY( PosY );
	unit->SetVelX( 50 );
	unit->SetVelY( 50 );
	unit->SetPath(Path);
	// Add unit to Entity Manager
	EM->AddEntity( unit );
}
/////////////////////////////////////////////////////////////////////////////
// Function		: SpawnUnits
// Notes		: helper function for spawning units
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::GodSpawnUnits(CSGD_DirectInput* pDI){
	if(m_bPlayerOne)
	{
		if(pDI->KeyPressed(DIK_SPACE))
		{
			// Loop through Path 1 waypoints
			for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints().size(); ++i )
			{
				// Cursor close to waypoint
				CWaypoint* wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[i];
				if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
				{
					// Spawn unit
					SpawnUnit( 1, true, (float)wpt->GetPos().m_nPosY );
					break;
				}
			}

			// Loop through Path 2 waypoints
			for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints().size(); ++i )
			{
				// Cursor close to waypoint
				CWaypoint* wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[i];
				if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
				{
					// Spawn unit
					SpawnUnit( 2, true, (float)wpt->GetPos().m_nPosY );
					break;
				}
			}

			// Loop through Path 3 waypoints
			for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints().size(); ++i )
			{
				// Cursor close to waypoint
				CWaypoint* wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints()[i];
				if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
				{
					// Spawn unit
					SpawnUnit( 3, true, (float)wpt->GetPos().m_nPosY );
					break;
				}
			}
		}
	}
	else
	{
		if(IsAi)
		{
		}
		else
		{
			if(pDI->KeyPressed(DIK_NUMPAD0))
			{
				// Loop through Path 1 waypoints
				for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints().size(); ++i )
				{
					// Cursor close to waypoint
					CWaypoint* wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[i];
					if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
					{
						// Spawn unit
						SpawnUnit( 1, false, (float)wpt->GetPos().m_nPosY );
						break;
					}
				}

				// Loop through Path 2 waypoints
				for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints().size(); ++i )
				{
					// Cursor close to waypoint
					CWaypoint* wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[i];
					if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
					{
						// Spawn unit
						SpawnUnit( 2, false, (float)wpt->GetPos().m_nPosY );
						break;
					}
				}

				// Loop through Path 3 waypoints
				for( unsigned int i = 0; i < CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints().size(); ++i )
				{
					// Cursor close to waypoint
					CWaypoint* wpt = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetWaypoints()[i];
					if( GetPosY() + GetHeight()/2 > wpt->GetPos().m_nPosY - SPAWNRANGE && GetPosY() + GetHeight()/2 < wpt->GetPos().m_nPosY + SPAWNRANGE )
					{
						// Spawn unit
						SpawnUnit( 3, false, (float)wpt->GetPos().m_nPosY );
						break;
					}
				}
			}
		}
	}
}
/////////////////////////////////////////////////////////////////////////////
// Function		: IsCloseToShip
// Return		: If the other ship is within range
// Notes		: helper function checks if it is close to the ship on the other team
/////////////////////////////////////////////////////////////////////////////
bool CPlayerShip::IsCloseToShip(CMovingObject* OtherShip){
	tVector2D ToTarget = {OtherShip->GetPosX() - GetShip()->GetPosX(), 
		OtherShip->GetPosY() - GetShip()->GetPosY() };

	if( Vector2DLength(ToTarget) < 200 )
		return true;
	return false;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: IsAboveUnit
// Notes		: helper function checks if the cursor is over the top of the unit
/////////////////////////////////////////////////////////////////////////////
CMovingObject* CPlayerShip::IsAboveUnit(){
	CTeam* OtherTeam;
	if(m_bPlayerOne)
		OtherTeam = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2();
	else
		OtherTeam = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1();
	vector<CBaseUnit*> PathUnits;
	for(unsigned int path = 0; path < 3; path++){
		switch(path){
		case 0:{
			PathUnits = OtherTeam->GetPath1Units();
			break;}
		case 1:{
			PathUnits = OtherTeam->GetPath2Units();
			break;}
		case 2:{
			PathUnits = OtherTeam->GetPath3Units();
			break;}
		}
		for(unsigned int i = 0; i < PathUnits.size(); ++i){
			CBaseUnit* unit = PathUnits[i];
			int center = (int)GetPosX() + GetWidth() / 2;
			if(center > unit->GetPosX() && center < unit->GetPosX() + unit->GetWidth()){
				center = (int)GetPosY() + GetHeight() / 2;
				if(center > unit->GetPosY() && center < unit->GetPosY() + unit->GetHeight()){
					return unit;
				}
			}
		}
	}
	return nullptr;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: IsAboveUnit
// Notes		: helper function checks if the cursor is over the top of a
//					structure build point
/////////////////////////////////////////////////////////////////////////////
CWaypoint* CPlayerShip::IsAboveBuildpoint(){
	CWaypoint* pt = nullptr;
	CWaypoint* selected = nullptr;
	vector<CWaypoint*> BuildPts;
	for(unsigned int path = 0; path < 3 && selected == nullptr; path++){
		switch(path){
		case 0:{
			BuildPts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetBuildpoints();
			break;}
		case 1:{
			BuildPts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetBuildpoints();
			break;}
		case 2:{
			BuildPts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetBuildpoints();
			break;}
		}
		for(unsigned int iter = 0; iter < BuildPts.size(); ++iter){
			pt = BuildPts[iter];
			//Correct X range
			if(GetPosX() < pt->GetPos().m_nPosX && GetPosX() + GetWidth() > pt->GetPos().m_nPosX){
				//Correct Y range
				if(GetPosY() < pt->GetPos().m_nPosY && GetPosY() + GetHeight() > pt->GetPos().m_nPosY){
					selected = pt;
					break;
				}
			}
		}
	}
	//Checks if a barricade is already placed there
	if(selected != nullptr){
		CBarricade* barr;
		for(unsigned int i = 0; i < CEntityManager::GetInstance()->m_Barricades.size(); ++i){
			barr = CEntityManager::GetInstance()->m_Barricades[i];
			if( barr->GetPosX() + barr->GetWidth()  / 2 == selected->GetPos().m_nPosX && 
				barr->GetPosY() + barr->GetHeight() / 2 == selected->GetPos().m_nPosY){
					selected = nullptr;
					break;
			}
		}
	}
	return selected;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Render
// Notes		: Renders the player ship to the screen
/////////////////////////////////////////////////////////////////////////////
void CPlayerShip::Render(){

	CBitmapFont* font = CGame::GetInstance()->GetFont();

	CSGD_Direct3D * m_pD3D = CSGD_Direct3D::GetInstance();

	if(AnimationInfo->GetIsPlaying() == true)
	{
		SPosition tractor;
		tractor.m_nPosX = GetShip()->GetPos().m_nPosX + (GetShip()->GetWidth() / 2);
		tractor.m_nPosY = GetShip()->GetPos().m_nPosY + GetShip()->GetHeight() - 5;
		AnimSystem->Render(tractor,AnimationInfo,0.75f);
	}

	if(m_bPlayerOne)
	{
		float baseHealth = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->GetBase()->GetHealth() / CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->GetBase()->GetMaxHealth() * 200.0f;
		RECT HealthOutline = { (LONG)(0), (LONG)(0), (LONG)(200), (LONG)(25) };
		RECT Health = { (LONG)(0), (LONG)(0), (LONG)(baseHealth), (LONG)(25) };
		m_pD3D->DrawRect(Health, D3DCOLOR_ARGB(255,255,0,0));
		m_pD3D->DrawHollowRect(HealthOutline, D3DCOLOR_ARGB(255,0,0,0),2);

		RECT ShieldOutline = { (LONG)(0), (LONG)(26), (LONG)(175), (LONG)(50) };

		RECT Shield = { (LONG)(0), (LONG)(26), (LONG)(100/175 * CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->GetBase()->GetShield()->GetHealth()), (LONG)(50) };
		m_pD3D->DrawRect(Shield, D3DCOLOR_ARGB(255,0,255,255));
		m_pD3D->DrawHollowRect(ShieldOutline, D3DCOLOR_ARGB(255,0,0,0),2);

		RECT PlayerHealthRed = { (LONG)m_cShip->GetPos().m_nPosX, (LONG)m_cShip->GetPos().m_nPosY - 5, (LONG)m_cShip->GetPos().m_nPosX + m_cShip->GetWidth(), (LONG)m_cShip->GetPos().m_nPosY + 10 };


		int right = (int)(m_cShip->GetPos().m_nPosX + (m_cShip->GetWidth() * (GetHealth() / GetTotalHealth())));
		RECT PlayerHealthGreen = { (LONG)m_cShip->GetPos().m_nPosX, (LONG)m_cShip->GetPos().m_nPosY - 5, (LONG)right, (LONG)m_cShip->GetPos().m_nPosY + 10 };

		RECT Background;

		switch(GetSelectedUnit())
		{
		case 1:
			Background.left = (LONG)(15);
			Background.top = (LONG)(383);
			Background.right = (LONG)(48);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[0], 15, 384, 0.5f,0.5f);
			break;

		case 2:
			Background.left = (LONG)(15);
			Background.top = (LONG)(384);
			Background.right = (LONG)(48);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[1], 15, 384, 0.5f, 0.5f);
			break;
		case 3:
			Background.left = (LONG)(15);
			Background.top = (LONG)(384);
			Background.right = (LONG)(48);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[2], 15, 384, 0.5f, 0.5f);
			break;
		case 4:
			Background.left = (LONG)(15);
			Background.top = (LONG)(384);
			Background.right = (LONG)(48);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[3], 15, 384, 0.5f, 0.5f);
			break;
		case 5:
			Background.left = (LONG)(15);
			Background.top = (LONG)(384);
			Background.right = (LONG)(78);
			Background.bottom = (LONG)(408);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[4], 15, 384, 0.5f, 0.5f);
			break;

		}
		switch((int)(CLevelManager::GetInstance()->GetCurrLevel()->GetLevelP1(m_nSelectedUnit-1)))
		{
		case 1:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 16, 360, 0.5f,0.5f);
			break;

		case 2:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 8, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 24, 360, 0.5f,0.5f);
			break;

		case 3:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 0, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 16, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 32, 360, 0.5f,0.5f);
			break;

		case 4:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 0, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 16, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 32, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 16, 345, 0.5f,0.5f);
			break;
		case 5:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 0, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 16, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 32, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 8, 345, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 24, 345, 0.5f,0.5f);
			break;

		default: 
			break;
		}
		m_pD3D->DrawRect(PlayerHealthRed,D3DCOLOR_ARGB(255,255,0,0));
		m_pD3D->DrawRect(PlayerHealthGreen,D3DCOLOR_ARGB(255,0,255,0));
		m_pD3D->DrawHollowRect(PlayerHealthRed,D3DCOLOR_ARGB(255,0,0,0));
	}
	else
	{
		float baseHealth = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->GetBase()->GetHealth() / CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->GetBase()->GetMaxHealth() * 200.0f;
		RECT HealthOutline = { (LONG)(600), (LONG)(0), (LONG)(800), (LONG)(25) };
		RECT Health = { (LONG)(800 - baseHealth), (LONG)(0), (LONG)(800), (LONG)(25) };
		m_pD3D->DrawRect(Health, D3DCOLOR_ARGB(255,255,0,0));
		m_pD3D->DrawHollowRect(HealthOutline, D3DCOLOR_ARGB(255,0,0,0),2);

		RECT ShieldOutline = { (LONG)(625), (LONG)(26), (LONG)(800), (LONG)(50) };

		RECT Shield = { (LONG)(800 - ((100/175)*CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->GetBase()->GetShield()->GetHealth())), (LONG)(26), (LONG)(800), (LONG)(50) };
		m_pD3D->DrawRect(Shield, D3DCOLOR_ARGB(255,0,255,255));
		m_pD3D->DrawHollowRect(ShieldOutline, D3DCOLOR_ARGB(255,0,0,0),2);

		RECT PlayerHealthRed = { (LONG)m_cShip->GetPos().m_nPosX, (LONG)m_cShip->GetPos().m_nPosY - 5, (LONG)m_cShip->GetPos().m_nPosX + m_cShip->GetWidth(), (LONG)m_cShip->GetPos().m_nPosY + 10 };

		int right = (int)m_cShip->GetPos().m_nPosX + (m_cShip->GetWidth() * (int)(GetHealth() / GetTotalHealth()));
		RECT PlayerHealthGreen = { (LONG)m_cShip->GetPos().m_nPosX, (LONG)m_cShip->GetPos().m_nPosY - 5, (LONG)right, (LONG)m_cShip->GetPos().m_nPosY + 10 };

		RECT Background;

		switch(GetSelectedUnit())
		{
		case 1:
			Background.left = (LONG)(752);
			Background.top = (LONG)(384);
			Background.right = (LONG)(785);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[0], 752, 384, 0.5f, 0.5f);
			break;
		case 2:
			Background.left = (LONG)(752);
			Background.top = (LONG)(384);
			Background.right = (LONG)(785);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[1], 752, 384, 0.5f, 0.5f);
			break;
		case 3:
			Background.left = (LONG)(752);
			Background.top = (LONG)(384);
			Background.right = (LONG)(785);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[2], 752, 384, 0.5f, 0.5f);
			break;
		case 4:
			Background.left = (LONG)(752);
			Background.top = (LONG)(384);
			Background.right = (LONG)(785);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[3], 752, 384, 0.5f, 0.5f);
			break;

		case 5:
			Background.left = (LONG)(722);
			Background.top = (LONG)(384);
			Background.right = (LONG)(785);
			Background.bottom = (LONG)(416);
			CSGD_Direct3D::GetInstance()->DrawRect(Background, D3DCOLOR_ARGB(255,0,0,0));
			CSGD_TextureManager::GetInstance()->Draw(m_Units[4], 752, 384, 0.5f, 0.5f);
			break;
		}

		switch((int)(CLevelManager::GetInstance()->GetCurrLevel()->GetLevelP2(m_nSelectedUnit-1)))
		{
		case 1:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 768, 360, 0.5f,0.5f);
			break;

		case 2:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 760, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 776, 360, 0.5f,0.5f);
			break;

		case 3:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 752, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 768, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 784, 360, 0.5f,0.5f);
			break;

		case 4:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 752, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 768, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 784, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 768, 345, 0.5f,0.5f);
			break;
		case 5:
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 752, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 768, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 784, 360, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 760, 345, 0.5f,0.5f);
			CSGD_TextureManager::GetInstance()->Draw(m_nStarImg, 776, 345, 0.5f,0.5f);
			break;

		default: 
			break;
		}

		m_pD3D->DrawRect(PlayerHealthRed,D3DCOLOR_ARGB(255,255,0,0));
		m_pD3D->DrawRect(PlayerHealthGreen,D3DCOLOR_ARGB(255,0,255,0));
		m_pD3D->DrawHollowRect(PlayerHealthRed,D3DCOLOR_ARGB(255,0,0,0));

	}

	CMovingObject::Render();

	m_cShip->Render();

	if( m_bPlayerOne && IsAboveBuildpoint() != nullptr )
	{
		// TEST - simple way of getting image
		CBarricade* barricade = new CBarricade(m_bPlayerOne);
		RECT rect;
		SetRect(&rect, 0, 0, barricade->GetWidth(), barricade->GetHeight());
		CSGD_TextureManager::GetInstance()->Draw( barricade->GetImage(), (int)GetPosX() + GetWidth()/2 - barricade->GetWidth()/2, (int)GetPosY() + GetHeight()/2 - barricade->GetHeight()/2,
			1.0f, 1.0f, &rect, barricade->GetWidth() / 2.0f, barricade->GetHeight() / 2.0f, D3DX_PI * barricade->GetRotation(),
			D3DCOLOR_ARGB(128, 255,255,255) );
		delete barricade;
	}

}
/////////////////////////////////////////////////////////////////////////////
// Function		: Is Above Barricade
// Return		: The waypoint location of the barricade to upgrade
// Notes		: Checks if the ship is above a barricade
/////////////////////////////////////////////////////////////////////////////
CBarricade* CPlayerShip::IsAboveBarricade(){
	CWaypoint* pt = nullptr;
	CWaypoint* selected = nullptr;
	vector<CWaypoint*> CheckPts;
	//Check if over a barricade location, track which
	for(unsigned int path = 0; path < 3 && selected == nullptr; path++){
		switch(path){
		case 0:{
			CheckPts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetBuildpoints();
			break;}
		case 1:{
			CheckPts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetBuildpoints();
			break;}
		case 2:{
			CheckPts = CLevelManager::GetInstance()->GetCurrLevel()->GetPath3()->GetBuildpoints();
			break;}
		}
		for(unsigned int iter = 0; iter < CheckPts.size(); ++iter){
			pt = CheckPts[iter];
			//Check X range
			if(GetPosX() < pt->GetPos().m_nPosX && GetPosX() + GetWidth() > pt->GetPos().m_nPosX){
				//Check Y range
				if(GetPosY() < pt->GetPos().m_nPosY && GetPosY() + GetHeight() > pt->GetPos().m_nPosY){
					selected = pt;
					break;
				}
			}
		}
	}
	//Make sure there is already a barricade in place
	bool inPlace = false;
	CBarricade* barr = nullptr;
	if(selected != nullptr){
		for(unsigned int i = 0; i < CEntityManager::GetInstance()->m_Barricades.size(); ++i){
			barr = CEntityManager::GetInstance()->m_Barricades[i];
			if( barr->GetPosX() + barr->GetWidth()  / 2 == selected->GetPos().m_nPosX &&
				barr->GetPosY() + barr->GetHeight() / 2 == selected->GetPos().m_nPosY){
					inPlace = true;
					break;
			}
		}
	}
	if(!inPlace){
		selected = nullptr;
		barr = nullptr;
	}
	return barr;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Is above own base
// Return		: If they are above their team's base
// Notes		: Checks if the player ship is above their own base
/////////////////////////////////////////////////////////////////////////////
bool CPlayerShip::IsAboveOwnBase(){
	CBase *base;
	if(m_bPlayerOne){
		base = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam1()->GetBase();
	}
	else{
		base = CLevelManager::GetInstance()->GetCurrLevel()->GetTeam2()->GetBase();
	}
	RECT reticle = {(LONG)(GetPosX()), (LONG)(GetPosY()), (LONG)(GetPosX() + GetWidth()), (LONG)(GetPosY() + GetHeight())};
	RECT baseRect = {(LONG)(base->GetPosX()), (LONG)(base->GetPosY()), 
		(LONG)(base->GetPosX() + base->GetWidth()), (LONG)(base->GetPosY() + base->GetHeight())};
	RECT intersect;
	if(IntersectRect(&intersect, &reticle, &baseRect) == TRUE){
		return true;
	}
	return false;
}